package com.formula.distribution.example.controller;

import com.alibaba.fastjson.JSON;
import com.formula.distribution.encrypt.annotation.Decrypt;
import com.formula.distribution.encrypt.annotation.Encrypt;
import com.formula.distribution.example.entity.User;
import com.formula.distribution.example.service.IUserService;
import com.formula.distribution.idempotent.annotation.ExtApiIdempotent;
import com.formula.distribution.idempotent.base.Constants;
import com.formula.distribution.limit.annotation.RateLimit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.interceptor.CacheInterceptor;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author:bo
 * @email:
 * @date 2018/11/29 9:53
 * @introduce
 **/
@Slf4j
@RestController
@RequestMapping("user")
public class UserController {


    @Autowired
    IUserService userService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    @GetMapping("find/id")
    public User findById(@RequestParam("id") Integer id) {
        userService.findById(id);
//        userService.findById2(id);
//        userService.findById3(id);
//        userService.findById4(id);
//        userService.findById5(id);

        return userService.findById(id);
    }

    @GetMapping("find/id2")
    @RateLimit(limit = 20)
    @Encrypt
    @Decrypt
    public User findById2(@RequestParam("id") Integer id) {

        return userService.findById2(id);
    }

    @GetMapping("test")
    public String test() {
        CacheInterceptor cacheInterceptor = new CacheInterceptor();
        CacheResolver cacheResolver = cacheInterceptor.getCacheResolver();

        return null;
    }


    @PostMapping("postBody")
    @Encrypt
    @Decrypt
    public String postBody(@RequestBody User user) {
        return JSON.toJSONString(user);
    }

    @PostMapping("post")
    @Encrypt
    @Decrypt
    public String post(User user) {
        return JSON.toJSONString(user);
    }


    @PostMapping("Decrypt")
    @Decrypt
    public String Decrypt(@RequestBody User user) {
        return JSON.toJSONString(user);
    }

    @PostMapping("Encrypt")
    @Encrypt
    public String Encrypt(@RequestBody User user) {
        return JSON.toJSONString(user);
    }

    private static final long TIME_OUT = 60 * 60;
    private static final String KEY_NAME = "KEY_NAME";

    /**
     * 接口幂等性测试
     *
     * @return
     */
    @PostMapping("get/token")
    public String getToken() {
        log.info("获取TOKEN");
        String token = KEY_NAME + System.currentTimeMillis();
        stringRedisTemplate.opsForValue().set(token, token, TIME_OUT, TimeUnit.SECONDS);
        return null;
    }

    /**
     * 接口幂等性测试
     *
     * @return
     */
    @PostMapping("idempotent")
    @ExtApiIdempotent(Constants.HEAD)
    public String idempotent() {
        log.info("接口幂等性测试");
        return null;
    }


    @PostMapping(value = "lock/test")
    public String getValue() throws IOException {
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        int i = 0;
        while (i < 10) {
            final int num = i;
            executorService.submit(() -> {
                try {
                    String result = userService.getValue("sleep" + num);
                    System.err.println("线程:[" + Thread.currentThread().getName() + "]拿到结果=》" + result + new Date().toLocaleString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            i++;
        }
        System.in.read();
        return "sss";
    }


}
